package com.woniu.cq.springboot_mybatisplus_shiro.conf;

import com.woniu.cq.springboot_mybatisplus_shiro.comment.EncryptUtil;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Author: Klaus
 * @Date: 2020/9/2 16:19
 */
@Configuration
public class ShiroConfig {

    @Bean
    public Realm realm(){
        ShiroRealm shiroRealm = new ShiroRealm();
//      将算法配置设置到realm中
        shiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return shiroRealm;
    }

    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        //用户输入的密码  数据库中的正确密码
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        //设置算法的名字(在算法类中进行配置的)
        hashedCredentialsMatcher.setHashAlgorithmName(EncryptUtil.ALGORITHM_NAME);
        //设置hash迭代的次数(在算法类中进行配置的)
        hashedCredentialsMatcher.setHashIterations(EncryptUtil.HASH_ITERATIONS);

        return hashedCredentialsMatcher;
    }


    /**
     * shiro 过滤器链配置
     * @return
     */
    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition(){
        DefaultShiroFilterChainDefinition sfcd = new DefaultShiroFilterChainDefinition();
        //  xxx路径  -> 某个过滤器
        //public enum DefaultFilter

        //不拦截 anon
        //需要登录  user
        //登出     logout

        //不拦截
        sfcd.addPathDefinition("/css/**","anon");
        sfcd.addPathDefinition("/js/**","anon");
        sfcd.addPathDefinition("/images/**","anon");
        sfcd.addPathDefinition("/html/**","anon");
        sfcd.addPathDefinition("/fonts/**","anon");
        sfcd.addPathDefinition("/layui/**","anon");
        sfcd.addPathDefinition("/","anon");
        sfcd.addPathDefinition("/login.html","anon");
        sfcd.addPathDefinition("/login","anon");
        sfcd.addPathDefinition("login","anon");
        sfcd.addPathDefinition("/index.html","anon");
        sfcd.addPathDefinition("/reg.html","anon");

        //登出
        sfcd.addPathDefinition("/logout","logout");
        //拦截
        sfcd.addPathDefinition("/**","user");

        return sfcd;
    }

    //Shiro缓存
    @Bean
    public CacheManager cacheManager(){
        return new MemoryConstrainedCacheManager();
    }

//    //解决权限注解与RequestMapping冲突
//    @Bean
//    public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator(){
//        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator();
//        /**
//         * setUsePrefix(false)用于解决一个奇怪的bug。在引入spring aop的情况下。
//         * 在@Controller注解的类的方法中加入@RequiresRole等shiro注解，会导致该方法无法映射请求，导致返回404。
//         * 加入这项配置能解决这个bug
//         */
//        defaultAdvisorAutoProxyCreator.setUsePrefix(true);
//        return defaultAdvisorAutoProxyCreator;
//    }




//    @Bean
//    public DefaultWebSecurityManager securityManager() {
//        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//        //安全管理器注入领域对象(封装好了认证授权的方法)
//        securityManager.setRealm(realm());
//        return securityManager;
//    }
//
//    //用于扫描Shiro的注解和使用SpringAop来完成权限校验
//    @Bean
//    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
//        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
//        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
//        return authorizationAttributeSourceAdvisor;
//    }
//
//    @Bean
//    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
//        return new LifecycleBeanPostProcessor();
//    }
//    @Bean
//    @DependsOn({"lifecycleBeanPostProcessor"})
//    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
//        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
//        advisorAutoProxyCreator.setProxyTargetClass(true);
//        return advisorAutoProxyCreator;
//    }
}
